package com.uyayo.oms.system.controller;

import com.uyayo.framework.common.annotation.MethodName;
import com.uyayo.framework.common.exception.CodeMultipleException;
import com.uyayo.framework.common.exception.RecordNotExistException;
import com.uyayo.framework.message.model.Result;
import com.uyayo.framework.common.util.CodeUtil;
import com.uyayo.framework.common.util.FtpUtil;
import com.uyayo.framework.message.model.Tree;
import com.uyayo.oms.system.biz.FileBiz;
import com.uyayo.oms.system.biz.ParamBiz;
import com.uyayo.oms.system.constants.FileDirConstants;
import com.uyayo.oms.system.model.FileInfo;
import com.uyayo.oms.system.util.FileDownload;
import com.uyayo.oms.system.util.PathUtil;
import com.uyayo.oms.system.vo.SysFileVO;
import com.uyayo.framework.pagehelper.pojo.PageBean;
import com.uyayo.framework.pagehelper.pojo.PageResult;
import com.uyayo.oms.system.wrap.SysFileWrap;
import com.uyayo.system.authority.entity.SysUser;
import com.uyayo.system.config.dto.SysFileDTO;
import com.uyayo.system.config.entity.SysFile;
import com.uyayo.system.config.entity.SysServer;
import com.uyayo.system.config.model.SysFileCondition;
import com.uyayo.system.config.service.SysFileService;
import com.uyayo.system.config.service.SysServerService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.dozer.DozerBeanMapper;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 *
 * 文件的controller
 *
 * @author 乐乐科技.胡逢君
 * @date 2015-4-13下午4:03:35
 * @version 1.0
 */
@Controller
@RequestMapping("/system/config/file")
public class SysFileController {

	private final DozerBeanMapper dozerBeanMapper;

	private final SysFileService sysFileService;

	private final SysServerService sysServerService;

	private final ParamBiz paramBiz;

	private final FileBiz fileBiz;

	private  final MessageSource messageSource;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	public SysFileController(DozerBeanMapper dozerBeanMapper, SysFileService sysFileService, SysServerService sysServerService, ParamBiz paramBiz, FileBiz fileBiz, MessageSource messageSource) {
		this.dozerBeanMapper = dozerBeanMapper;
		this.sysFileService = sysFileService;
		this.sysServerService = sysServerService;
		this.paramBiz = paramBiz;
		this.fileBiz = fileBiz;
		this.messageSource = messageSource;
	}

	@RequestMapping(value = "index",method = RequestMethod.GET)
	@MethodName(value="系统管理->系统配置->文件管理")
	public ModelAndView files_main(ModelAndView modelAndView) {
		modelAndView.setViewName(paramBiz.getManagerTemplatesPrefix()+"system/config/file/index");
		modelAndView.addObject("fileDir",FileDirConstants.splitFileDir(FileDirConstants.SYSTEM_FILE));
		return modelAndView;
	}
	
	@ResponseBody
	@RequestMapping(value = "grid",method = RequestMethod.GET)
	@MethodName(value="系统管理->系统配置->文件管理->查询列表",type=2)
	public PageResult<SysFileWrap> selectFiles(@RequestParam(value = "offset",required = false, defaultValue = "1") Integer start, //第多少行之后开始
										   @RequestParam(value = "limit", required = false, defaultValue = "10") Integer pageSize, String sort, String order, SysFileCondition sysFileCondition) throws Exception {
		PageBean<SysFile> pageBean=new PageBean<>();
		try {
			pageBean = sysFileService.selectFileByPage((start / pageSize) + 1, pageSize,sort,order,sysFileCondition);
		} catch (Exception e) {
			e.printStackTrace();
		}

		SysServer sysServer = new SysServer();
		sysServer.setType(0);
		sysServer.setStatus(1);
		sysServer = sysServerService.selectSysServer(sysServer).get(0);
		PageResult<SysFileWrap> pageResult = new PageResult<>();
		SysServer finalSysServer = sysServer;
		pageResult.setRows(pageBean.getList().stream().map(sysFile -> {
			SysFileWrap sysFileWrap;
			sysFileWrap = dozerBeanMapper.map(sysFile, SysFileWrap.class);
			sysFileWrap.setUrlFull(finalSysServer.getUrl()+sysFileWrap.getUrl());
			return sysFileWrap;
		}).collect(Collectors.toList()));
		pageResult.setTotal(pageBean.getTotalCount());
		return pageResult;
	}



	@ResponseBody
	@RequestMapping(value = "siteInnerImage",method = RequestMethod.GET)
	@MethodName(value="系统管理->系统配置->文件管理->查询列表",type=2)
	public List<FileInfo> siteInnerImage(String fileDir) throws Exception {
		List<FileInfo> list = null;
		try {
			list = fileBiz.findAll(fileDir);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}


	/**
	 * 进入文件表单
	 */
	@RequestMapping(value = "add", method = RequestMethod.GET)
	public String add(Model model) {
		model.addAttribute("prefixDir",FileDirConstants.splitFileDirByTime(FileDirConstants.OTHER_FILE));
		return paramBiz.getManagerTemplatesPrefix()+"system/config/file/add";
	}

	/**
	 * 新建一个文件
	 */
	@ResponseBody
	@RequestMapping(value = "add", method = RequestMethod.POST)
	@MethodName(value="系统管理->系统配置->文件管理->保存文件",type=2)
	synchronized public Result saveFiles(MultipartFile file, HttpServletRequest request, @Validated SysFileVO sysFileVO, Errors errors) {
		SysFile sysFile = new SysFile();
		SysFileDTO sysFileDTO;
		try {
			if (errors.hasErrors()) {
				return Result.errorAndMsg(errors.getFieldError().getDefaultMessage());
			}
			if (null == file || file.isEmpty()) {
				String message = messageSource.getMessage("save.fail",new Object[]{}, request.getLocale());
				return Result.error(400, message);
			}
			Subject subject = SecurityUtils.getSubject();
			SysUser sysUser = (SysUser) subject.getPrincipal();

			DateTime dateTime = new DateTime();
			String fileDateTimePath = dateTime.toString("/yyyy/MM/dd");
			String filePath;

			if(StringUtils.isEmpty(sysFileVO.getPrefixDir())){
				filePath = fileDateTimePath;
			}else {
				filePath = sysFileVO.getPrefixDir();
			}
			String code = CodeUtil.getTimeSequenceAsRandomCode();
			//取文件扩展名
			String originalFilename = file.getOriginalFilename();
			String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
			String fileName = code+ext;
			sysFile.setCode(code);
			if(StringUtils.isEmpty(sysFileVO.getTitle())){
				sysFile.setTitle(originalFilename.substring(0,originalFilename.lastIndexOf("."))); //获取除后缀1位的名称
			}else{
				sysFile.setTitle(sysFileVO.getTitle());
			}
			sysFile.setSize(BigDecimal.valueOf(file.getSize()).divide(BigDecimal.valueOf(1024)));
			sysFile.setName(fileName);
			sysFile.setCreateTime(new Date());
			sysFile.setCreateBy(sysUser.getLoginname());
			sysFile.setType(sysFileVO.getType());
			sysFile.setStatus(sysFileVO.getStatus());
			sysFile.setSortOrder(sysFileVO.getSortOrder());
			sysFile.setRemark(sysFileVO.getRemark());
			sysFile.setDescription(sysFileVO.getDescription());
			sysFileDTO = sysFileService.createFile(sysFile,filePath,fileName,file.getInputStream());
			if(sysFileDTO==null){
				String message = messageSource.getMessage("save.fail",new Object[]{}, request.getLocale());
				logger.info(message);
				return Result.error(400,message);
			}
		} catch (CodeMultipleException e){
			String message = messageSource.getMessage("code.multiple.error",new Object[]{}, request.getLocale());
			logger.info(message,e.getMessage());
			return Result.error(400,message);
		} catch (Exception e) {
			String message = messageSource.getMessage("server.error.500",new Object[]{}, request.getLocale());
			logger.error(message,e);
			return Result.error(500, message);
		}
		String message = messageSource.getMessage("save.success",new Object[]{}, request.getLocale());
		return Result.success(200,message,sysFileDTO);
	}

	@ResponseBody
	@RequestMapping(value = "update", method = RequestMethod.GET)
	@RequiresPermissions("system:config:file:update")
	public ModelAndView update(ModelAndView modelAndView,int id) {
		SysFile sysFile = null;
		try {
			sysFile = sysFileService.getFilesById(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		modelAndView.addObject("prefixDir",FileDirConstants.splitFileDirByTime(FileDirConstants.OTHER_FILE));
		modelAndView.addObject("sysFile",sysFile);
		modelAndView.setViewName(paramBiz.getManagerTemplatesPrefix()+"system/config/file/update");
		return modelAndView;
	}
	
	/**
	 * 修改一个文件
	 */
	@ResponseBody
	@RequestMapping("update")
	@MethodName(value="系统管理->系统配置->文件管理->修改文件",type=2)
	synchronized public Result updateFiles(MultipartFile file, HttpServletRequest request, @Validated SysFileVO sysFileVO, Errors errors) {
		try {
			if (errors.hasErrors()) {
				return Result.errorAndMsg(errors.getFieldError().getDefaultMessage());
			}
			if (sysFileVO==null || sysFileVO.getId()==null) {
				String message = messageSource.getMessage("parameter.error",new Object[]{}, request.getLocale());
				logger.error(message);
				return Result.error(400,message);
			}
			SysFile sysFile = sysFileService.getFilesById(sysFileVO.getId());
			if(sysFile==null) {
				return Result.error(400, "请选择需修改的记录！");
			}
			Subject subject = SecurityUtils.getSubject();
			SysUser sysUser = (SysUser) subject.getPrincipal();

			DateTime dateTime = new DateTime();
			String fileDateTimePath = dateTime.toString("/yyyy/MM/dd");
			String filePath;
			if(StringUtils.isEmpty(sysFileVO.getPrefixDir())){
				filePath = fileDateTimePath;
			}else {
				filePath = sysFileVO.getPrefixDir();
			}
			//取文件扩展名
			String originalFilename = file.getOriginalFilename();
			String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
			String fileName =  sysFile.getCode()+ext;
			boolean status;
			if(StringUtils.isEmpty(sysFileVO.getTitle())){
				sysFile.setTitle(originalFilename.substring(0,originalFilename.lastIndexOf("."))); //获取除后缀1位的名称
			}else{
				sysFile.setTitle(sysFileVO.getTitle());
			}
			sysFile.setSize(BigDecimal.valueOf(file.getSize()).divide(BigDecimal.valueOf(1024)));
			sysFile.setName(fileName);
			sysFile.setUpdateTime(new Date());
			sysFile.setUpdateBy(sysUser.getLoginname());
			sysFile.setType(sysFileVO.getType());
			sysFile.setStatus(sysFileVO.getStatus());
			sysFile.setSortOrder(sysFileVO.getSortOrder());
			sysFile.setRemark(sysFileVO.getRemark());
			sysFile.setDescription(sysFileVO.getDescription());
			status = sysFileService.updateFile(sysFile,filePath,fileName,file.getInputStream());
			if(!status){
				String message = messageSource.getMessage("save.fail",new Object[]{}, request.getLocale());
				logger.info(message);
				return Result.error(400,message);
			}
		} catch (CodeMultipleException e){
			String message = messageSource.getMessage("code.multiple.error",new Object[]{}, request.getLocale());
			logger.info(message,e.getMessage());
			return Result.error(400,message);
		} catch (RecordNotExistException e) {
			return Result.error(400, "请选择需修改的记录！");
		} catch (Exception e) {
			String message = messageSource.getMessage("server.error.500",new Object[]{}, request.getLocale());
			logger.error(message,e);
			return Result.error(500, message);
		}
		String message = messageSource.getMessage("save.success",new Object[]{}, request.getLocale());
		return Result.successAndMsg(message);
	}
	
	
	/**
	 * 下载模版
	 */
	@RequestMapping(value="/down/{id}")
	public void downFile(HttpServletRequest request,HttpServletResponse response,@PathVariable("id") Long id) throws Exception{

		SysFile sysFile = sysFileService.getFilesById(id);
		if(sysFile==null) {
			return;
		}

		SysServer sysServer = sysServerService.getSysServerById(sysFile.getServerId());
		String url = sysFile.getUrl();
		String retrievePath = url.substring(url.lastIndexOf(sysServer.getUploadDirectory()),url.length());
		if(sysServer.getType()==1){
			String ftpHost = sysServer.getHost();
			int ftpPort = sysServer.getPort();
			String ftpUsername = sysServer.getUsername();
			String ftpPassword = sysServer.getPassword();
			FtpUtil.downloadFile(ftpHost,ftpPort,ftpUsername,ftpPassword,url.substring(url.lastIndexOf(sysServer.getUploadDirectory()),url.lastIndexOf(sysFile.getName())),sysFile.getName(),PathUtil.getRootClassPath()+"/download");
			String realPath = PathUtil.getRootClassPath()+"/download"+"/"+sysFile.getName();
			FileDownload.downloadFile(response,realPath, sysFile.getName());
		}else{
			String realPath = PathUtil.getRootClassPath()+retrievePath;
			FileDownload.downloadFile(response,realPath, sysFile.getName());
		}
	}


	/**
	 * 进入全局参数查看页面
	 */
	@RequestMapping(value = "view", method = RequestMethod.GET)
	@MethodName(value="系统管理->系统配置->文件管理->查看文件",type=2)
	@RequiresPermissions("system:config:file:view")
	public ModelAndView show(ModelAndView modelAndView,Integer id) {
		SysFile sysFile = new SysFile();
		try {
			sysFile = sysFileService.getFilesById(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		modelAndView.addObject("sysFile",sysFile);
		modelAndView.setViewName(paramBiz.getManagerTemplatesPrefix()+"system/config/file/view");
		return modelAndView;
	}
	
	
	
	/**
	 * 删除文件
	 */
	@ResponseBody
	@RequestMapping("delete")
	@MethodName(value="系统管理->系统配置->文件管理->删除文件",type=2)
	public Result deleteFiles(HttpServletRequest request, Long id) {
		try {
			if (id==null) {
				String message = messageSource.getMessage("parameter.error",new Object[]{}, request.getLocale());
				logger.error(message);
				return Result.error(400,message);
			}
			boolean s = sysFileService.deleteFile(id);
			if(!s){
				String message = messageSource.getMessage("delete.fail",new Object[]{}, request.getLocale());
				logger.error(message);
				return Result.error(400,message);
			}
		}catch (RecordNotExistException e) {
			return Result.error(400, "请选择需删除的记录！");
		} catch (Exception e) {
			String message = messageSource.getMessage("server.error.500",new Object[]{}, request.getLocale());
			logger.error(message,e);
			return Result.error(500,message);
		}

		String message = messageSource.getMessage("delete.success",new Object[]{}, request.getLocale());
		logger.error(message);
		return Result.success(200,message);
	}
	
}
